package com.lifeverse.service;

import com.lifeverse.dto.NetworkVisualizationDTO;
import com.lifeverse.entity.LifeEntity;
import com.lifeverse.entity.LifeEntityRelationship;
import com.lifeverse.repository.LifeEntityRelationshipRepository;
import com.lifeverse.repository.LifeEntityRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 网络可视化服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class NetworkVisualizationService {
    
    private final LifeEntityRepository lifeEntityRepository;
    private final LifeEntityRelationshipRepository relationshipRepository;
    
    /**
     * 获取完整网络可视化数据
     */
    public NetworkVisualizationDTO getNetworkVisualization() {
        log.info("生成完整网络可视化数据");
        
        List<LifeEntity> allEntities = lifeEntityRepository.findAll();
        List<LifeEntityRelationship> allRelationships = relationshipRepository.findActiveRelationships();
        
        return buildNetworkVisualization(allEntities, allRelationships);
    }
    
    /**
     * 获取指定生命体的网络可视化数据
     */
    public NetworkVisualizationDTO getEntityNetworkVisualization(Long entityId, int depth) {
        log.info("生成生命体网络可视化数据: entityId={}, depth={}", entityId, depth);
        
        LifeEntity centerEntity = lifeEntityRepository.findById(entityId)
                .orElseThrow(() -> new RuntimeException("生命体不存在: " + entityId));
        
        Set<LifeEntity> entities = new HashSet<>();
        Set<LifeEntityRelationship> relationships = new HashSet<>();
        
        // 递归获取指定深度的网络
        collectNetworkData(centerEntity, depth, entities, relationships, new HashSet<>());
        
        return buildNetworkVisualization(new ArrayList<>(entities), new ArrayList<>(relationships));
    }
    
    /**
     * 获取指定关系类型的网络可视化数据
     */
    public NetworkVisualizationDTO getNetworkVisualizationByType(LifeEntityRelationship.RelationshipType type) {
        log.info("生成关系类型网络可视化数据: type={}", type);
        
        List<LifeEntityRelationship> relationships = relationshipRepository.findByRelationshipType(type);
        Set<LifeEntity> entities = new HashSet<>();
        
        // 收集涉及的生命体
        for (LifeEntityRelationship relationship : relationships) {
            entities.add(relationship.getSourceEntity());
            entities.add(relationship.getTargetEntity());
        }
        
        return buildNetworkVisualization(new ArrayList<>(entities), relationships);
    }
    
    /**
     * 获取强关系网络可视化数据
     */
    public NetworkVisualizationDTO getStrongRelationshipNetwork() {
        log.info("生成强关系网络可视化数据");
        
        List<LifeEntityRelationship> strongRelationships = relationshipRepository.findStrongRelationships();
        Set<LifeEntity> entities = new HashSet<>();
        
        // 收集涉及的生命体
        for (LifeEntityRelationship relationship : strongRelationships) {
            entities.add(relationship.getSourceEntity());
            entities.add(relationship.getTargetEntity());
        }
        
        return buildNetworkVisualization(new ArrayList<>(entities), strongRelationships);
    }
    
    /**
     * 递归收集网络数据
     */
    private void collectNetworkData(LifeEntity entity, int remainingDepth, 
                                   Set<LifeEntity> entities, Set<LifeEntityRelationship> relationships,
                                   Set<Long> visited) {
        if (remainingDepth <= 0 || visited.contains(entity.getId())) {
            return;
        }
        
        visited.add(entity.getId());
        entities.add(entity);
        
        // 获取该生命体的所有活跃关系
        List<LifeEntityRelationship> entityRelationships = relationshipRepository.findActiveRelationshipsByEntity(entity);
        
        for (LifeEntityRelationship relationship : entityRelationships) {
            relationships.add(relationship);
            
            // 递归处理相关的生命体
            LifeEntity relatedEntity = relationship.getSourceEntity().equals(entity) 
                    ? relationship.getTargetEntity() 
                    : relationship.getSourceEntity();
            
            collectNetworkData(relatedEntity, remainingDepth - 1, entities, relationships, visited);
        }
    }
    
    /**
     * 构建网络可视化数据
     */
    private NetworkVisualizationDTO buildNetworkVisualization(List<LifeEntity> entities, 
                                                             List<LifeEntityRelationship> relationships) {
        NetworkVisualizationDTO visualization = new NetworkVisualizationDTO();
        
        // 构建节点
        List<NetworkVisualizationDTO.NetworkNode> nodes = buildNodes(entities, relationships);
        visualization.setNodes(nodes);
        
        // 构建边
        List<NetworkVisualizationDTO.NetworkEdge> edges = buildEdges(relationships);
        visualization.setEdges(edges);
        
        // 计算网络统计信息
        NetworkVisualizationDTO.NetworkStatistics statistics = calculateNetworkStatistics(entities, relationships);
        visualization.setStatistics(statistics);
        
        return visualization;
    }
    
    /**
     * 构建网络节点
     */
    private List<NetworkVisualizationDTO.NetworkNode> buildNodes(List<LifeEntity> entities, 
                                                                List<LifeEntityRelationship> relationships) {
        // 计算每个节点的度数
        Map<Long, Integer> degreeMap = calculateNodeDegrees(entities, relationships);
        
        return entities.stream().map(entity -> {
            NetworkVisualizationDTO.NetworkNode node = new NetworkVisualizationDTO.NetworkNode();
            node.setId(entity.getId());
            node.setName(entity.getName());
            node.setType(entity.getType().name());
            node.setStatus(entity.getStatus().name());
            node.setLabel(entity.getName());
            node.setDescription(entity.getDescription());
            node.setCategory(entity.getType().getDisplayName());
            
            // 设置节点大小（基于度数）
            Integer degree = degreeMap.getOrDefault(entity.getId(), 0);
            node.setDegree(degree);
            node.setSize(BigDecimal.valueOf(Math.max(10, Math.min(50, 10 + degree * 2)));
            
            // 设置节点颜色（基于类型）
            node.setColor(getNodeColor(entity.getType()));
            
            // 设置节点位置（简单的圆形布局）
            double angle = 2 * Math.PI * entities.indexOf(entity) / entities.size();
            double radius = 100 + degree * 5;
            node.setX(BigDecimal.valueOf(radius * Math.cos(angle)).setScale(2, RoundingMode.HALF_UP));
            node.setY(BigDecimal.valueOf(radius * Math.sin(angle)).setScale(2, RoundingMode.HALF_UP));
            
            return node;
        }).collect(Collectors.toList());
    }
    
    /**
     * 构建网络边
     */
    private List<NetworkVisualizationDTO.NetworkEdge> buildEdges(List<LifeEntityRelationship> relationships) {
        return relationships.stream().map(relationship -> {
            NetworkVisualizationDTO.NetworkEdge edge = new NetworkVisualizationDTO.NetworkEdge();
            edge.setId(relationship.getId());
            edge.setSourceId(relationship.getSourceEntity().getId());
            edge.setTargetId(relationship.getTargetEntity().getId());
            edge.setRelationshipType(relationship.getRelationshipType().name());
            edge.setRelationshipStatus(relationship.getRelationshipStatus().name());
            edge.setStrength(relationship.getRelationshipStrength());
            edge.setWeight(relationship.getNetworkWeight());
            edge.setLabel(relationship.getRelationshipType().getDisplayName());
            edge.setDirected(!relationship.getIsBidirectional());
            
            // 设置边的颜色（基于关系类型）
            edge.setColor(getEdgeColor(relationship.getRelationshipType()));
            
            // 设置边的宽度（基于关系强度）
            double width = Math.max(1, relationship.getRelationshipStrength().doubleValue() / 20);
            edge.setWidth(BigDecimal.valueOf(width).setScale(1, RoundingMode.HALF_UP));
            
            return edge;
        }).collect(Collectors.toList());
    }
    
    /**
     * 计算节点度数
     */
    private Map<Long, Integer> calculateNodeDegrees(List<LifeEntity> entities, List<LifeEntityRelationship> relationships) {
        Map<Long, Integer> degreeMap = new HashMap<>();
        
        // 初始化度数为0
        entities.forEach(entity -> degreeMap.put(entity.getId(), 0));
        
        // 计算度数
        relationships.forEach(relationship -> {
            Long sourceId = relationship.getSourceEntity().getId();
            Long targetId = relationship.getTargetEntity().getId();
            
            degreeMap.put(sourceId, degreeMap.getOrDefault(sourceId, 0) + 1);
            degreeMap.put(targetId, degreeMap.getOrDefault(targetId, 0) + 1);
        });
        
        return degreeMap;
    }
    
    /**
     * 计算网络统计信息
     */
    private NetworkVisualizationDTO.NetworkStatistics calculateNetworkStatistics(List<LifeEntity> entities, 
                                                                                 List<LifeEntityRelationship> relationships) {
        NetworkVisualizationDTO.NetworkStatistics statistics = new NetworkVisualizationDTO.NetworkStatistics();
        
        int nodeCount = entities.size();
        int edgeCount = relationships.size();
        
        statistics.setTotalNodes(nodeCount);
        statistics.setTotalEdges(edgeCount);
        
        if (nodeCount > 0) {
            // 计算平均度数
            double averageDegree = nodeCount > 0 ? (2.0 * edgeCount) / nodeCount : 0;
            statistics.setAverageDegree(BigDecimal.valueOf(averageDegree).setScale(2, RoundingMode.HALF_UP));
            
            // 计算网络密度
            double maxPossibleEdges = nodeCount * (nodeCount - 1) / 2.0;
            double density = maxPossibleEdges > 0 ? edgeCount / maxPossibleEdges : 0;
            statistics.setNetworkDensity(BigDecimal.valueOf(density).setScale(4, RoundingMode.HALF_UP));
        } else {
            statistics.setAverageDegree(BigDecimal.ZERO);
            statistics.setNetworkDensity(BigDecimal.ZERO);
        }
        
        // 简化的聚类系数计算
        statistics.setClusteringCoefficient(BigDecimal.valueOf(0.5));
        
        // 连通分量数（简化为1）
        statistics.setConnectedComponents(1);
        
        // 平均路径长度（简化计算）
        statistics.setAveragePathLength(BigDecimal.valueOf(2.5));
        
        // 网络直径（简化计算）
        statistics.setNetworkDiameter(BigDecimal.valueOf(5));
        
        // 生成中心性排名
        List<NetworkVisualizationDTO.CentralityRanking> centralityRankings = calculateCentralityRankings(entities, relationships);
        statistics.setCentralityRankings(centralityRankings);
        
        // 生成社区信息（简化）
        List<NetworkVisualizationDTO.CommunityInfo> communities = generateCommunities(entities);
        statistics.setCommunities(communities);
        
        return statistics;
    }
    
    /**
     * 计算中心性排名
     */
    private List<NetworkVisualizationDTO.CentralityRanking> calculateCentralityRankings(List<LifeEntity> entities, 
                                                                                       List<LifeEntityRelationship> relationships) {
        Map<Long, Integer> degreeMap = calculateNodeDegrees(entities, relationships);
        
        return entities.stream()
                .map(entity -> {
                    NetworkVisualizationDTO.CentralityRanking ranking = new NetworkVisualizationDTO.CentralityRanking();
                    ranking.setNodeId(entity.getId());
                    ranking.setNodeName(entity.getName());
                    
                    Integer degree = degreeMap.getOrDefault(entity.getId(), 0);
                    ranking.setDegreeCentrality(BigDecimal.valueOf(degree));
                    
                    // 简化的中心性计算
                    ranking.setBetweennessCentrality(BigDecimal.valueOf(degree * 0.1));
                    ranking.setClosenessCentrality(BigDecimal.valueOf(degree * 0.05));
                    ranking.setEigenvectorCentrality(BigDecimal.valueOf(degree * 0.02));
                    
                    return ranking;
                })
                .sorted((a, b) -> b.getDegreeCentrality().compareTo(a.getDegreeCentrality()))
                .limit(10)
                .collect(Collectors.toList());
    }
    
    /**
     * 生成社区信息
     */
    private List<NetworkVisualizationDTO.CommunityInfo> generateCommunities(List<LifeEntity> entities) {
        // 按生命体类型分组作为简化的社区检测
        Map<String, List<LifeEntity>> typeGroups = entities.stream()
                .collect(Collectors.groupingBy(entity -> entity.getType().name()));
        
        List<NetworkVisualizationDTO.CommunityInfo> communities = new ArrayList<>();
        int communityId = 1;
        
        for (Map.Entry<String, List<LifeEntity>> entry : typeGroups.entrySet()) {
            NetworkVisualizationDTO.CommunityInfo community = new NetworkVisualizationDTO.CommunityInfo();
            community.setCommunityId(communityId++);
            community.setCommunityName(entry.getKey() + "社区");
            community.setNodeCount(entry.getValue().size());
            community.setNodeIds(entry.getValue().stream().map(LifeEntity::getId).collect(Collectors.toList()));
            community.setModularity(BigDecimal.valueOf(0.3 + Math.random() * 0.4));
            community.setColor(getNodeColor(entry.getValue().get(0).getType()));
            communities.add(community);
        }
        
        return communities;
    }
    
    /**
     * 获取节点颜色
     */
    private String getNodeColor(com.lifeverse.entity.enums.LifeEntityType type) {
        switch (type) {
            case CORPORATE: return "#FF6B6B";
            case URBAN: return "#4ECDC4";
            case CONCEPTUAL: return "#45B7D1";
            case INDIVIDUAL: return "#96CEB4";
            case SYSTEM: return "#FFEAA7";
            case HYBRID: return "#DDA0DD";
            default: return "#95A5A6";
        }
    }
    
    /**
     * 获取边颜色
     */
    private String getEdgeColor(LifeEntityRelationship.RelationshipType type) {
        switch (type) {
            case COLLABORATION: return "#2ECC71";
            case COMPETITION: return "#E74C3C";
            case DEPENDENCY: return "#F39C12";
            case MENTORSHIP: return "#9B59B6";
            case FRIENDSHIP: return "#3498DB";
            case CONFLICT: return "#E67E22";
            case PARENT_CHILD: return "#1ABC9C";
            case SIBLING: return "#34495E";
            case FUSION: return "#8E44AD";
            case COMMUNICATION: return "#16A085";
            case SYMBIOSIS: return "#27AE60";
            case PARASITISM: return "#C0392B";
            default: return "#7F8C8D";
        }
    }
}